home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / c3 / pro24 / noteoff.c < prev    next >
Text File  |  1986-08-06  |  5KB  |  158 lines

  1. /* noteoff.c -- this module keeps track of pending note offs for adagio */
  2.  
  3. /*****************************************************************************
  4. *        Change Log
  5. *  Date        | Change
  6. *-----------+-----------------------------------------------------------------
  7. * 31-Dec-85 | Created changelog
  8. * 31-Dec-85 | Add c:\ to include directives
  9. *  1-Jan-86 | Declare getmem char * for lint consistency
  10. * 21-Jan-86 | note_offs can now turn off more than one note per call
  11. *****************************************************************************/
  12.  
  13. #include "cext.h"
  14. #include "stdio.h"
  15. #include "ctype.h"
  16. #include "adagio.h"
  17.  
  18. /* off_type is a structure containing note-off information */
  19.  
  20. typedef struct off_struct {
  21.     long when;
  22.     int voice;
  23.     int pitch;
  24.     struct off_struct *next;
  25. } *off_type;
  26.  
  27. private off_type free_off;        /* free list of off_type structures */
  28. private off_type off_events = NULL;    /* active list */
  29. extern char * getmem();
  30.  
  31. /****************************************************************************
  32. *    Routines declared in this module
  33. ****************************************************************************/
  34.  
  35.     boolean        note_offs();
  36. private off_type    off_alloc();
  37. private void        off_free();
  38.     void        off_init();
  39.     void        off_schedule();
  40.  
  41. /****************************************************************************
  42. *                note_offs
  43. * Inputs:
  44. *    long time: the current time
  45. * Outputs:
  46. *    return true if off list has more notes 
  47. * Effect: turn off notes if it is time 
  48. * Assumes:
  49. * Implementation:
  50. *    Find scheduled note off events in off_events, compare with time
  51. ****************************************************************************/
  52.  
  53. boolean note_offs(time)
  54. long time;
  55. {
  56.     off_type temp;
  57.     while (off_events != NULL && off_events->when <= time) {
  58.     midi_note((off_events->voice) + 1, off_events->pitch, 0);
  59.     temp = off_events;
  60.     off_events = off_events->next;
  61.     off_free(temp);
  62.     }
  63.     return (off_events != NULL);
  64. }
  65.  
  66. /****************************************************************************
  67. *                off_alloc
  68. * Outputs:
  69. *    returns off_type: an allocated note off structure
  70. * Effect:
  71. *    allocates a structure using getmem
  72. ****************************************************************************/
  73.  
  74. private off_type off_alloc()
  75. {
  76.     return (off_type) getmem(sizeof(struct off_struct));
  77. }
  78.  
  79. /****************************************************************************
  80. *                off_free
  81. * Inputs:
  82. *    off_type off: a structure to deallocate
  83. * Effect: 
  84. *    returns off to freelist
  85. ****************************************************************************/
  86.  
  87. private void off_free(off)
  88.     off_type off;
  89. {
  90.     off->next = free_off;
  91.     free_off = off;
  92. }
  93.  
  94. /****************************************************************************
  95. *                off_init
  96. * Effect: initialize this module
  97. * Assumes:
  98. *    only called once, otherwise storage is leaked
  99. ****************************************************************************/
  100.  
  101. void off_init()
  102. {
  103.     int i;
  104.     for (i = 0; i < 50; i++) off_free(off_alloc());
  105. }
  106.  
  107. /****************************************************************************
  108. *                off_schedule
  109. * Inputs:
  110. *    long offtime: time to turn note off
  111. *    int voice: the midi channel
  112. *    int pitch: the pitch
  113. * Effect: 
  114. *    schedules a note to be turned off
  115. * Assumes:
  116. *    note_offs will be called frequently to actually turn off notes
  117. ****************************************************************************/
  118.  
  119. void off_schedule(offtime, voice, pitch)
  120.     long offtime;
  121.     int voice, pitch;
  122. {
  123.     off_type off, ptr, prv;
  124.     /* allocate off */
  125.     if ((off = free_off) == NULL) {
  126.     off = off_alloc();
  127.     } else free_off = off->next;
  128.  
  129.     if (off == NULL) {
  130.     fprintf(stderr, "out of space for note off events");
  131.     musicterm();
  132.     exit(1);
  133.     }
  134.  
  135.     off->when = offtime;
  136.     off->voice = voice;
  137.     off->pitch = pitch;
  138.     /* insert into list of off events */
  139.     ptr = off_events;
  140.     if (ptr == NULL || offtime <= ptr->when) {
  141.     off->next = ptr;
  142.     off_events = off;
  143.     } else {
  144.     while (ptr != NULL && offtime > ptr->when) {
  145.         prv = ptr;
  146.         ptr = ptr->next;
  147.     }
  148.     prv->next = off;
  149.     off->next = ptr;
  150.     }
  151. /*
  152.  *    printf("off_schedule(%ld, %d, %d): \n", offtime, voice, pitch);
  153.  *    for (ptr = off_events; ptr != NULL; ptr = ptr->next) {
  154.  *    printf("    %ld: %d, %d\n", ptr->when, ptr->voice, ptr->pitch);
  155.  *    }
  156.  */
  157. }
  158.